package ex55.mm.flow.impound.quote.common.kit;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import ex55.mm.flow.impound.quote.exchange.api.ExchangeException;

import java.math.BigDecimal;


public class JsonWrapper {

    private final JSONObject json;
    private final JSONArray array;

    public static JsonWrapper parseFromString(String text) throws ExchangeException {
        try {
            if(text.startsWith("[")){
               JSONArray jsonArray = JSON.parseArray(text);
                return new JsonWrapper(jsonArray);
            }

            JSONObject jsonObject = (JSONObject) JSON.parse(text);
            if (jsonObject != null) {
                return new JsonWrapper(jsonObject);
            } else {
                throw ExceptionKit.handler(new IllegalArgumentException("[Json] Unknown error when parse: " + text));
            }
        } catch (Exception e) {
            throw ExceptionKit.handler(e);
        }
    }

    public JsonWrapper(JSONObject json) {
        this(json, null);
    }
    public JsonWrapper(JSONArray array) {
        this(null, array);
    }
    public JsonWrapper(JSONObject json, JSONArray array) {
        this.json = json;
        this.array = array;
    }

    private void checkMandatoryField(String name) throws ExchangeException {
        if (!json.containsKey(name)) {
            throw ExceptionKit.handler(new IllegalArgumentException("[Json] Get json item field: " + name + " does not exist"));
        }
    }

    public boolean containKey(String name) {
        return json.containsKey(name);
    }

    public String getString(String name) throws ExchangeException {
        checkMandatoryField(name);
        try {
            return json.getString(name);
        } catch (Exception e) {
            throw ExceptionKit.handler(e);
        }
    }

    public String getStringOrDefault(String name, String def) throws ExchangeException {
        if (!containKey(name)) {
            return def;
        }
        return getString(name);
    }

    public boolean getBoolean(String name) throws ExchangeException {
        checkMandatoryField(name);
        try {
            return json.getBoolean(name);
        } catch (Exception e) {
            throw ExceptionKit.handler(e);
        }
    }

    public int getInteger(String name) throws ExchangeException {
        checkMandatoryField(name);
        try {
            return json.getInteger(name);
        } catch (Exception e) {
            throw ExceptionKit.handler(e);
        }
    }

    public Integer getIntegerOrDefault(String name, Integer defValue) throws ExchangeException {
        try {
            if (!containKey(name)) {
                return defValue;
            }
            return json.getInteger(name);
        } catch (Exception e) {
            throw ExceptionKit.handler(e);
        }
    }

    public long getLong(String name) throws ExchangeException {
        checkMandatoryField(name);
        try {
            return json.getLong(name);
        } catch (Exception e) {
            throw ExceptionKit.handler(e);
        }
    }

    public long getLongOrDefault(String name, long defValue) throws ExchangeException {
        try {
            if (!containKey(name)) {
                return defValue;
            }
            return json.getLong(name);
        } catch (Exception e) {
            throw ExceptionKit.handler(e);
        }
    }

    public BigDecimal getBigDecimal(String name) throws ExchangeException {
        checkMandatoryField(name);
        try {
            return new BigDecimal(json.getBigDecimal(name).stripTrailingZeros().toPlainString());
        } catch (Exception e) {
            throw ExceptionKit.handler(e);
        }
    }

    public BigDecimal getBigDecimalOrDefault(String name, BigDecimal defValue) throws ExchangeException {
        if (!containKey(name)) {
            return defValue;
        }
        try {
            return new BigDecimal(json.getBigDecimal(name).stripTrailingZeros().toPlainString());
        } catch (Exception e) {
            throw ExceptionKit.handler(e);
        }
    }

    public JsonWrapper getJsonObject(String name) throws ExchangeException {
        checkMandatoryField(name);
        return new JsonWrapper(json.getJSONObject(name));
    }

    public JSONObject getJson() {
        return json;
    }

    public JSONArray getArray() {
        return array;
    }

    public JsonWrapperArray getJsonArray(String name) throws ExchangeException {
        checkMandatoryField(name);
        JSONArray array = null;
        try {
            array = json.getJSONArray(name);
        } catch (Exception e) {
            throw ExceptionKit.handler(new IllegalArgumentException("[Json] Get array: " + name + " error"));
        }
        if (array == null) {
            throw ExceptionKit.handler(new IllegalArgumentException("[Json] Array: " + name + " does not exist"));
        }
        return new JsonWrapperArray(array);
    }
}
